Macros with Arguments

Contents|Index|Previous|Next
Macros with arguments

A simple macro always stands for exactly the same text, each time it is used. Macros can be more flexible when they accept arguments. Arguments are fragments of code that you supply each time the macro is used. These fragments are included in the expansion of the macro according to the directions in the macro definition. A macro that accepts arguments is called a function-like macro because the syntax for using it looks like a function call.

To define a macro that uses arguments, you write a #define directive with a list of argument names in parentheses after the name of the macro. The argument names may be any valid C identifiers, separated by commas and optionally whitespace. The open-parenthesis must follow the macro name immediately, with no space in between. For example, here is a macro that computes the minimum of two numeric values, as it is defined in many C programs:

    #define min(X, Y) ((X) < (Y) ? (X) : (Y))

This is not the best way to define a minimum macro in GNU C; see Duplication of side effects for more information. To use a macro that expects arguments, you write the name of the macro followed by a list of actual arguments in parentheses, separated by commas. The number of actual arguments you give must match the number of arguments the macro expects. Examples of use of the macro min include min (1, 2) and min (x + 28, *p).

The expansion text of the macro depends on the arguments you use. Each of the argument names of the macro is replaced, throughout the macro definition, with the corresponding actual argument. Using the same macro, min (as defined in the previous input example), min (1, 2) expands into the following output.

    ((1) < (2) ? (1) : (2))

1 has been substituted for X and 2 for Y. Likewise, min (x + 28, *p) expands into the following output.

    ((x + 28) < (*p) ? (x + 28) : (*p))

Parentheses in the actual arguments must balance; a comma within parentheses does not end an argument. However, there is no requirement for brackets or braces to balance, and they do not prevent a comma from separating arguments. Use the following input as an example.

    macro (array[x = y,x +1])

This passes two arguments to macro: array[x = y’ and ‘x +1]. If you want to supply array[x = y, x + 1] as an argument, you must write it as array[(x = y, x + 1)], which is equivalent C code.

After the actual arguments are substituted into the macro body, the entire result is appended to the front of the remaining input, and the check for macro calls continues. Therefore, the actual arguments can contain calls to other macros, either with or without arguments, or even to the same macro. The macro body can also contain calls to other macros. For example, min (min (a, b), c) expands into the following output.

    ((((a) < (b) ? (a) : (b))) < (c)
    ? (((a) < (b) ? (a) : (b)))
    : (c))

If a macro foo takes one argument, and you want to supply an empty argument, you must write at least some whitespace between the parentheses, like this: foo ( ). Just foo () is providing no arguments, which is an error if foo expects an argument. But foo0 () is the correct way to call a macro defined to take zero arguments, like the following example for input.

    #define foo0() : : :

If you use the macro name followed by something other than an open-parenthesis (after ignoring any spaces, tabs and comments that follow), it is not a call to the macro, and the preprocessor does not change what you have written. Therefore, it is possible for the same name to be a variable or function in your program as well as a macro, and you can choose in each instance whether to refer to the macro (if an actual argument list follows) or the variable or function (if an argument list does not follow).

Such dual use of one name could be confusing and should be avoided except when the two meanings are effectively synonymous: that is, when the name is both a macro and a function and the two have similar effects. You can think of the name simply as a function; use of the name for purposes other than calling it (such as, to take the address) will refer to the function, while calls will expand the macro and generate better but equivalent code. For example, you can use a function named min in the same source file that defines the macro. If you write &min with no argument list, you refer to the function. If you write min (x, bb), with an argument list, the macro is expanded. If you write (min) (a, bb), where the name min is not followed by an open-parenthesis, the macro is not expanded, so you wind up with a call to the function min.

You may not define the same name as both a simple macro and a macro with arguments.

In the definition of a macro with arguments, the list of argument names must follow the macro name immediately with no space in between your input. If there is a space after the macro name, the macro is defined as taking no arguments, and all the rest of the line is taken to be the expansion. The reason for this is that it is often useful to define a macro that takes no arguments and whose definition begins with an identifier in parentheses. This rule about spaces would use input like either one of the two following examples.

    #define FOO(x) - 1 / (x)

The previous example defines FOO to take an argument and expand into minus the reciprocal of that argument.

The following example defines BAR to take no argument and always expand into (x) -1 / (x)).

    #define BAR (x) - 1 / (x)

Note:
The uses of a macro with arguments can have spaces before the left parenthesis; it’s the definition where it matters whether there is a space.

Top|Contents|Index|Previous|Next